home *** CD-ROM | disk | FTP | other *** search
- Path: qns2.qns.com!not-for-mail
- From: mjarvis@qns2.qns.com (Michael Jarvis)
- Newsgroups: comp.lang.c
- Subject: Re: Hiding a password
- Date: 3 Mar 1996 14:12:11 -0600
- Organization: Questar Network Services
- Message-ID: <4hcuer$2q5@qns2.qns.com>
- References: <1996Feb29.224936.137160@forest>
- X-Newsreader: TIN [version 1.2 PL2]
-
- ebromber@forest.drew.edu (ebromber@forest.drew.edu) wrote:
- > I recently wrote a password program. However, there is one little flaw I
- > want to fix. When the password is entered, it is visible on the screen. I
- > was wondering if anyone knows how to hide the password by printing
- > asterisks instead of the actual character.
-
- From the comp.lang.c FAQ, available at
-
- ftp://rtfm.mit.edu/pub/usenet-by-group/comp.lang.c/C-FAQ-list
-
- 19.1: How can I read a single character from the keyboard without
- waiting for the RETURN key? How can I stop characters from
- being echoed on the screen as they're typed?
-
- A: Alas, there is no standard or portable way to do these things in
- C. Concepts such as screens and keyboards are not even
- mentioned in the Standard, which deals only with simple I/O
- "streams" of characters.
-
- At some level, interactive keyboard input is usually collected
- and presented to the requesting program a line at a time. This
- gives the operating system a chance to support input line
- editing (backspace/delete/rubout, etc.) in a consistent way,
- without requiring that it be built into every program. Only
- when the user is satisfied and presses the RETURN key (or
- equivalent) is the line made available to the calling program.
- Even if the calling program appears to be reading input a
- character at a time (with getchar() or the like), the first call
- blocks until the user has typed an entire line, at which point
- potentially many characters become available and many character
- requests (e.g. getchar() calls) are satisfied in quick
- succession.
-
- When a program wants to read each character immediately as it
- arrives, its course of action will depend on where in the input
- stream the line collection is happening and how it can be
- disabled. Under some systems (e.g. MS-DOS, VMS in some modes),
- a program can use a different or modified set of OS-level input
- calls to bypass line-at-a-time input processing. Under other
- systems (e.g. Unix, VMS in other modes), the part of the
- operating system responsible for serial input (often called the
- "terminal driver") must be placed in a mode which turns off line-
- at-a-time processing, after which all calls to the usual input
- routines (e.g. read(), getchar(), etc.) will return characters
- immediately. Finally, a few systems (particularly older, batch-
- oriented mainframes) perform input processing in peripheral
- processors which cannot be told to do anything other than line-
- at-a-time input.
-
- Therefore, when you need to do character-at-a-time input (or
- disable keyboard echo, which is an analogous problem), you will
- have to use a technique specific to the system you're using,
- assuming it provides one. Since comp.lang.c is oriented towards
- topics that C does deal with, you will usually get better
- answers to these questions by referring to a system-specific
- newsgroup such as comp.unix.questions or
- comp.os.msdos.programmer, and to the FAQ lists for these groups.
- Note that the answers are often not unique even across different
- variants of a system; bear in mind when answering system-
- specific questions that the answer that applies to your system
- may not apply to everyone else's.
-
- However, since these questions are frequently asked here, here
- are brief answers for some common situations.
-
- Some versions of curses have functions called cbreak(),
- noecho(), and getch() which do what you want. If you're
- specifically trying to read a short password without echo, you
- might try getpass(). Under Unix, you can use ioctl() to play
- with the terminal driver modes (CBREAK or RAW under "classic"
- versions; ICANON, c_cc[VMIN] and c_cc[VTIME] under System V or
- POSIX systems; ECHO under all versions), or in a pinch, system()
- and the stty command. (For more information, see <sgtty.h> and
- tty(4) under classic versions, <termio.h> and termio(4) under
- System V, or <termios.h> and termios(4) under POSIX.) Under MS-
- DOS, use getch() or getche(), or the corresponding BIOS
- interrupts. Under VMS, try the Screen Management (SMG$)
- routines, or curses, or issue low-level $QIO's with the
- IO$_READVBLK function code (and perhaps IO$M_NOECHO, and others)
- to ask for one character at a time. (It's also possible to set
- character-at-a-time or "pass through" modes in the VMS terminal
- driver.) Under other operating systems, you're on your own.
-
- (As an aside, note that simply using setbuf() or setvbuf() to
- set stdin to unbuffered will *not* generally serve to allow
- character-at-a-time input.)
-
- If you're trying to write a portable program, a good approach is
- to define your own suite of three functions to (1) set the
- terminal driver or input system into character-at-a-time mode
- (if necessary), (2) get characters, and (3) return the terminal
- driver to its initial state when the program is finished.
- (Ideally, such a set of functions might be part of the C
- Standard, some day.) The extended versions of this FAQ list
- (see question 20.40) contain examples of such functions for
- several popular systems.
-
- See also question 19.2.
-
- References: PCS Sec. 10 pp. 128-9, Sec. 10.1 pp. 130-1; POSIX
- Sec. 7.
-
- --
- Michael Jarvis | Finger for PGP Public key | QNSnet Technical Support
- mjarvis@qns.com | http://www.qns.com/~mjarvis | Questar Network Services
- GC3.1: GCS d s+++: a26 C++++ USLV++++$ P++++ L++ E--- W++ N++ !o K+ W-- !O
- M- !V PS+ PE Y+ PGP+ t+ 5 X R tv b+++ DI+++ D++ G+ e>++ h---(*) r+++ y+++
-